package com.neusoft.bizcore.activiti.listener;

import java.lang.reflect.Method;
import java.util.List;

import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.stereotype.Component;

import com.neusoft.bizcore.activiti.dto.PendingDataDTO;
import com.neusoft.bizcore.activiti.service.PendingDataService;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class ProcessEventListener extends ApplicationObjectSupport implements ActivitiEventListener {

    @Autowired
    private PendingDataService pendingDataService;

    @Override
    public void onEvent(final ActivitiEvent event) {
        final ActivitiEventType eventType = event.getType();
        if (ActivitiEventType.PROCESS_COMPLETED.equals(eventType)) {
            final String instanceId = event.getProcessInstanceId();
            final List<PendingDataDTO> list = this.pendingDataService.findByInstanceId(instanceId);
            if (CollectionUtils.isNotEmpty(list)) {
                list.stream().forEach(item -> {
                    try {
                        final Class<?> clazz = Class.forName(item.getClazzName());
                        final Method method = clazz.getMethod(item.getMethodName(), PendingDataDTO.class);
                        final Object obj = method.invoke(this.getApplicationContext().getBean(clazz), item);
                        if (obj != null) {
                            ProcessEventListener.log.info("result -> " + obj.toString());
                        }
                    } catch (final Exception e) {
                        e.printStackTrace();
                    }
                });
            }
        }
    }

    @Override
    public boolean isFailOnException() {
        return false;
    }
}
